#include "config.h"

#ifndef _ZWYlistgraph_
#define _ZWYlistgraph_

template <class tv, class te>
class _ZWYlistgraph_{
    class vnode
    {
    public:
        int order=-1;
        tv data=tv();
        te weight=te();
        te d;
        S status;
        vnode* next=NULL;
        vnode* pre=NULL;
        vnode(){};
        vnode(tv vtx, te w){data=vtx;weight=w;};
        vnode(int od,tv vtx,te w){order=od;data=vtx;weight=w;};
    };
    int num;
    std::vector<vnode*> vertex; 

public:
    list(){};
    ~list();
    int set_num(int n);
    int resize_graph(int n);
    tv set_vertex(int n, const tv& vtx);
    tv push_back(const tv& vtx);
    te set_edge(int i, int j, te weight);
    te get_edge(int i, int j) const;
    void init_single();
    void printdata();
    void printorder();
 };

template <class tv,class te>
list<tv,te>::~list(){
    for(auto it=vertex.begin();it!=vertex.end();++it){
        vnode* i=(*it);
        while(i!=NULL){
            vnode* p=i;
            i=i->next;
            delete p;
       }
    }
};

template<class tv,class te>
int list<tv,te>::set_num(int n){
    num=n;
    return num; 
};

template<class tv,class te>
inline int list<tv,te>::resize_graph(int n){
    this->set_num(n);
    vertex.resize(num,new vnode);
    return num;
};

template<class tv, class te>
tv list<tv,te>::push_back(const tv& vtx){
    this ->resize_graph(++num);
    this ->set_vertex(num-1,vtx);
    return vtx;
};

template <class tv,class te>
te list<tv,te>::set_edge(int i,int j,te weight){
    vnode* v=new vnode(j,vertex[j]->data,weight);
    vnode* n;
    for(n=vertex[i];n->next!=NULL;n=n->next);
    n->next=v;
    return weight;
};

template <class tv,class te>
te list<tv,te>::get_edge(int i,int j) const {
    vnode* n;
    for(n=vertex[i]->next;n!=NULL;n=n->next)
        if(n->order==j) return n->weight;
    return infinite_p(te);
};

template <class tv,class te>
void list<tv,te>::init_single(int s){
    for(auto it=vertex.begin();it!=vertex.end();++it){
        vnode* i=(*it);
        while(i!=NULL){
            if(i->order==s) i->d=0;else i->d=infinite_p(te());
        }
    }
};

template <class tv,class te>
void list<tv,te>::printdata(){
    for(auto it=vertex.begin();it!=vertex.end();++it){
        std::cout << (*it) -> data;
        vnode* i=(*it) ->next;
        while(i!=NULL){
            std::cout << "\n-" << i->weight << "->" << i->data;
            i=i->next;
        }
        std::cout << "\n";
    }
};

template <class tv,class te>
void list<tv,te>::printorder(){
    for(auto it=vertex.begin();it!=vertex.end();++it){
        std::cout << (*it)->order;
        vnode* i=(*it)->next;
        while(i!=NULL){
        std::cout << "\n-" << i->weight << "->" << i->order;
        i=i->next;
        }
        std::cout << "\n";
    }
};

#endif